package com.xuanyuan.base.utils;

import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.util.Log;


import com.xuanyuan.base.utils.ContextUtil;

import org.jetbrains.annotations.NotNull;

import java.io.File;
import java.util.Arrays;

import kotlin.jvm.internal.Intrinsics;

public class LogUtil {

    private static final String LOG_FILE_NAME = "log.log";
    private static final String COMMON_TAG = "Common";
    private static final int PRINT_LOG_LEVEL = Log.VERBOSE;

    /**
     * 日志开关是否开启
     */
    private static boolean isOpen = true;
    /**
     * 日志开关是否开启
     */
    public static boolean isOpenLog = true;

    /**
     * 判断日志开关是否开启
     *
     * @return 日志开关是否开启
     */
    public static boolean isOpen() {
        return isOpen;
    }

    /**
     * 初始化日志打印开关
     *
     * @param debug 是否打印日志
     */
    public static void initLogStatus(boolean debug) {
        isOpen = debug;
    }

    /**
     * 判断当前是否是Debug版本
     *
     * @param context 上下文
     * @return 当前是否是Debug版本
     */
    private static boolean isDebugStatus(Context context) {
        try {
            ApplicationInfo info = context.getApplicationInfo();
            return (info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
        } catch (Exception e) {
            return false;
        }
    }

    public static void v(Object object, String... msg) {
        if (PRINT_LOG_LEVEL <= Log.VERBOSE && isOpen) {
            Log.v(COMMON_TAG, mergeMessage(getTagName(object), msg));
        }
    }

    public static void d(Object object, String... msg) {
        if (isOpenLog) {

        } else {
            if (PRINT_LOG_LEVEL <= Log.DEBUG && isOpen) {
                Log.d(COMMON_TAG, mergeMessage(getTagName(object), msg));
            }
        }
    }

    public static void d(Class object, String... msg) {
        if (isOpenLog) {

        } else {
            if (PRINT_LOG_LEVEL <= Log.DEBUG && isOpen) {
                Log.d(COMMON_TAG, mergeMessage(getTagName(object), msg));
            }
        }
    }

    public static void i(Object object, String... msg) {
        if (isOpenLog) {

        } else {
            if (PRINT_LOG_LEVEL <= Log.INFO && isOpen) {
                Log.i(COMMON_TAG, mergeMessage(getTagName(object), msg));
            }
        }
    }

    public static void w(Object object, String... msg) {
        if (PRINT_LOG_LEVEL <= Log.WARN && isOpen) {
            Log.w(COMMON_TAG, mergeMessage(getTagName(object), msg));
        }
    }

    public static void e(Object object, String... msg) {
        if (isOpenLog) {

        } else {
            if (PRINT_LOG_LEVEL <= Log.ERROR && isOpen) {
                Log.e(COMMON_TAG, mergeMessage(getTagName(object), msg));
            }
        }
    }

    public static void v(Object object, Throwable tr, String... msg) {
        if (PRINT_LOG_LEVEL <= Log.VERBOSE && isOpen) {
            Log.v(COMMON_TAG, mergeMessage(getTagName(object), msg), tr);
        }
    }

    public static void d(Object object, Throwable tr, String... msg) {
        if (PRINT_LOG_LEVEL <= Log.DEBUG && isOpen) {
            Log.d(COMMON_TAG, mergeMessage(getTagName(object), msg), tr);
        }
    }

    public static void i(Object object, Throwable tr, String... msg) {
        if (PRINT_LOG_LEVEL <= Log.INFO && isOpen) {
            Log.i(COMMON_TAG, mergeMessage(getTagName(object), msg), tr);
        }
    }

    public static void w(Object object, Throwable tr, String... msg) {
        if (PRINT_LOG_LEVEL <= Log.WARN && isOpen) {
            Log.w(COMMON_TAG, mergeMessage(getTagName(object), msg),
                    tr);
        }
    }

    public static void e(Object object, Throwable tr, String... msg) {
        if (PRINT_LOG_LEVEL <= Log.ERROR && isOpen) {
            Log.e(COMMON_TAG, mergeMessage(getTagName(object), msg),
                    tr);
        }
    }

    public static void v(Object object, String msg, Throwable tr) {
        if (PRINT_LOG_LEVEL <= Log.VERBOSE && isOpen) {
            Log.v(COMMON_TAG, mergeMessage(getTagName(object), msg), tr);
        }
    }

    public static void d(Object object, String msg, Throwable tr) {
        if (PRINT_LOG_LEVEL <= Log.DEBUG && isOpen) {
            Log.d(COMMON_TAG, mergeMessage(getTagName(object), msg), tr);
        }
    }

    public static void i(Object object, String msg, Throwable tr) {
        if (PRINT_LOG_LEVEL <= Log.INFO && isOpen) {
            Log.i(COMMON_TAG, mergeMessage(getTagName(object), msg), tr);
        }
    }

    public static void w(Object object, String msg, Throwable tr) {
        if (PRINT_LOG_LEVEL <= Log.WARN && isOpen) {
            Log.w(COMMON_TAG, mergeMessage(getTagName(object), msg),
                    tr);
        }
    }

    public static void e(Object object, String msg, Throwable tr) {
        if (PRINT_LOG_LEVEL <= Log.ERROR && isOpen) {
            Log.e(COMMON_TAG, mergeMessage(getTagName(object), msg),
                    tr);
        }
    }

    private static String getTagName(Object object) {
        if (object instanceof Class) {
            return ((Class) object).getSimpleName();
        } else if (object instanceof String) {
            return (String) object;
        } else {
            return object.getClass().getSimpleName();
        }
    }

    public static boolean isLogSwitchOpen() {
        try {
            File logFile = getLogFile();
            return logFile.exists();
        } catch (Exception e) {
            return false;
        }
    }

    public static boolean checkLogSwitch(boolean isOpen) {
        try {
            File logFile = getLogFile();
            return isOpen ? logFile.createNewFile() : logFile.delete();
        } catch (Exception e) {
            return false;
        }
    }

    private static File getLogFile() {
        File externalFile = ContextUtil.getContext().getExternalFilesDir(null);
        return new File(externalFile, LOG_FILE_NAME);
    }

    private static String mergeMessage(String tag, String... msgArray) {
        StringBuilder result = new StringBuilder();
        result.append("[").append(tag).append("] ");
        if (null != msgArray && msgArray.length > 0) {
            for (String msg : msgArray) {
                result.append(msg);
            }
        }
        return result.toString();
    }


    private static final String TAG = "TAG";

    // below is default tag
    public static void i(String msg) {
        if (msg == null) {
            msg = "";
        }
        if (isOpenLog) {

        } else {
            if (isOpen) {
                Log.i(TAG, msg);
            }
        }
    }


    public static void d(String msg) {
        if (msg == null) {
            msg = "";
        }
        if (isOpenLog) {

        } else {
            if (isOpen) {
                Log.d(TAG, msg);
            }
        }
    }

    public static void e(String msg) {
        if (msg == null) {
            msg = "";
        }
        if (isOpenLog) {

        } else {
            if (isOpen) {
                Log.e(TAG, msg);
            }
        }
    }

    public static void v(String msg) {
        if (msg == null) {
            msg = "";
        }
        if (isOpenLog) {

        } else {
            if (isOpen) {
                Log.v(TAG, msg);
            }
        }
    }

    // below is custom tag
    public static void i(String tag, String msg) {
        if (msg == null) {
            msg = "";
        }
        if (isOpenLog) {

        } else {
            if (isOpen) {
                Log.i(tag, msg);
            }
        }
    }

    public static void d(String tag, String msg) {
        if (msg == null) {
            msg = "";
        }
        if (isOpenLog) {

        } else {
            if (isOpen) {
                Log.d(tag, msg);
            }
        }
    }

    public static void e(String tag, String msg) {
        if (msg == null) {
            msg = "";
        }
        if (isOpenLog) {

        } else {
            if (isOpen) {
                Log.e(tag, msg);
            }
        }
    }

    public static void v(String tag, String msg) {
        if (msg == null) {
            msg = "";
        }
        if (isOpenLog) {

        } else {
            if (isOpen) {
                Log.v(tag, msg);
            }
        }
    }


    public static final void msg(String tag, Object msg) {
        Intrinsics.checkNotNullParameter(msg, "msg");
        String[] info = autoJumpLogInfo(4);
        String newMsg = info[1] + info[2] + " --->> " + msg;
        if (isOpenLog) {

        } else {
            if (isOpen) {
                Log.d(tag, newMsg);
            }
        }
    }

    public static final void msg(Object... msg) {
        Intrinsics.checkNotNullParameter(msg, "msg");
        String tag = "log";
        String[] info = autoJumpLogInfo(4);
        String newMsg = info[1] + info[2] + " --->> " + Arrays.toString(msg);

        if (isOpenLog) {

        } else {
            if (isOpen) {
                Log.d(tag, newMsg);
            }
        }
    }

    @NotNull
    public static final String[] autoJumpLogInfo(int stackCount) {
        String[] infos = new String[]{"", "", ""};
        StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();

        infos[0] = stackTrace[stackCount].getClassName().substring(stackTrace[stackCount].getClassName().lastIndexOf(".") + 1);
        infos[1] = stackTrace[stackCount].getMethodName();
        infos[2] = "(" + stackTrace[stackCount].getFileName() + ":" + stackTrace[stackCount].getLineNumber() + ")";
        return infos;
    }
}
